package typejump.engine;

import java.util.LinkedList;
import java.util.concurrent.CopyOnWriteArrayList;

import typejump.commands.*;
import typejump.objects.Surface;
import typejump.objects.SwagDropItem;

/**
 * Stores and executes all text commands
 * @author g
 *
 */
public class CommandManager {

	private final Object commandLock = new Object();
	private LinkedList<String> commandQueue = new LinkedList<String>();
	private CopyOnWriteArrayList<TextCommand> commandList = new CopyOnWriteArrayList<TextCommand>();
	
	public CommandManager() {
		initCommands();
	}
	
	public Iterable<TextCommand> commands() {
		return commandList;
	}
	
	
	public void addCommand(String command) {
		synchronized (commandLock) {
			commandQueue.add(command);
		}
	}
	
	public void processCommands() {
		synchronized (commandLock) {
			while (commandQueue.size() > 0) {
				String command = commandQueue.poll();
				processCommand(command);
			}
		}
	}
	
	private void initCommands() {
		commandList.add(new Jump());
		commandList.add(new LongJump());
		commandList.add(new GoRight());
		commandList.add(new Hover());
		commandList.add(new Fall());
		commandList.add(new Stop());
		commandList.add(new Slowfall());
		
		commandList.add(new DevEnableArrowKeys());
		commandList.add(new DevDisableArrowKeys());
		commandList.add(new DevReset());
		commandList.add(new DevRaiseGround());
		commandList.add(new DevLowerGround());
		commandList.add(new DevStopGround());
		commandList.add(new DevExit());
		commandList.add(new DevGrab());
		commandList.add(new DevAddSwag());
		commandList.add(new DevInfiniteSwag());
		commandList.add(new DevFiniteSwag());
		commandList.add(new DevGridSnap());
		commandList.add(new DevLevel());
		commandList.add(new DevShowEditor());
		commandList.add(new DevEnablePanning());
		commandList.add(new DevCOP());
		commandList.add(new DevFocusPlayer());
		commandList.add(new DevClearLevel());
		commandList.add(new DevSparkle());
		commandList.add(new DevColors());
		commandList.add(new DevKill());
		commandList.add(new DevDelete());
		
		commandList.add(new DevSpawnObject(Surface.class, "block"));
		commandList.add(new DevSpawnObject(SwagDropItem.class, "swagdrop"));
	}
	
	private void processCommand(String command) {
		// Note that TextCommands may be case-sensitive
	
		boolean found = false;
		for (TextCommand tc : commandList) {
			if (tc.matches(command)) {
				tc.act(command);
				found = true;
				break;
			}
		}
	}
}
